local LoginModel = class("LoginModel")
local json = require("quick.json")

local UserBaseInfo = require("app.public.dao.UserBaseInfo")

function LoginModel:ctor()
	
	self.zoneListDict = {}
	self.visitedZoneList = {}
	self.recommendZoneList = {}
	self.recommendZone = nil
	self.zoneCount = -1
	self.account = nil
	self.token = nil
	self.rolesDict = {}

	-- 海外  亚服 欧服 美服
	self._selectZoneListTag = nil

	-- 所有服务器类表
	self._allZoneServers = {}
end

-- status 1：新开，2：火爆，3：畅通，4：维护 5：推荐
function LoginModel:JsonToZone(jsonStr)
	local zoneData = {
		id = tonumber(jsonStr.id),
		name = tostring(jsonStr.name),
		addr = tostring(jsonStr.addr),
		status = tostring(jsonStr.status),
		first_opentime = tonumber(jsonStr.first_opentime or 0) or 0,
		utc = jsonStr.utc,
		gatehost = jsonStr.gatehost,
		mergeId = tonumber(jsonStr.merge_id or 0) or 0,
	}

	-- 微信／QQ，修改name
	-- local wgPlatform = app.channelAPI:getWGPlatform()
	-- if wgPlatform == Enums.MSDK_PLATFORM.QQ then
	-- 	zoneData.name = "QQ" .. "-".. zoneData.name
	-- elseif wgPlatform == Enums.MSDK_PLATFORM.WX then
	-- 	zoneData.name = string.format("微信-%s", zoneData.name) --@ignore
	-- end
	return zoneData
end

function LoginModel:parseRecommendZone(jsonStr)
	if jsonStr then
		self.recommendZone = self:JsonToZone(jsonStr)
	end
end

function LoginModel:hasRecommendZone()
	return #self.recommendZoneList > 0
end

function LoginModel:getRecommendZone()
	return self.recommendZone
end

function LoginModel:getRecommendZoneList()
	return self.recommendZoneList
end

function LoginModel:parseVisitedZone(jsonStr, isNotNeedSort)
	self.visitedZoneList={}
	if jsonStr then
		for i,jsonObj in ipairs(jsonStr) do
			if jsonObj.server then
				local zoneData = self:JsonToZone(jsonObj.server)
                zoneData.roleNum = 0
                zoneData.lastVisitTS = jsonObj.LastVisitTS

				table.insert(self.visitedZoneList, zoneData)
			end
		end
		if not isNotNeedSort then
			table.sort( self.visitedZoneList, function(l,r) 
				return l.lastVisitTS > r.lastVisitTS
			end)
		end
	end
end

function LoginModel:getVisitedZoneById(id)
	local ret = nil
	for _,zoneData in pairs(self.visitedZoneList) do
		if zoneData.id==tonumber(id) then
			ret = zoneData
			break
		end
	end
	return ret
end

function LoginModel:getLastLoginZone()
	if #self.visitedZoneList > 0 then
		return self.visitedZoneList[1]
	elseif self.recommendZone then
		return self.recommendZone
	else
		return self.recommendZoneList[1]
	end
end

function LoginModel:hasVisitedZone()
	return #self.visitedZoneList > 0 
end

function LoginModel:cleanFriendZoneList()
	self._friendZoneList = nil
end

function LoginModel:getZoneById(id)
	for _ ,visitedZone in pairs(self.visitedZoneList) do
		if id == visitedZone.id then
			return visitedZone
		end
	end

	local zoneInfo = self._allZoneServers[id]

	if zoneInfo then
		return zoneInfo
	end

	if self._friendZoneList then
		for _,v in pairs(self._friendZoneList) do
            if v.serverInfo.id == id then
                return v.serverInfo
            end
        end
	end


	if self.recommendZone and id == self.recommendZone.id then
		return self.recommendZone
	end
end

function LoginModel:getZoneListByPage(pageNum)
	assert(pageNum and type(pageNum)=="number")
	return self.zoneListDict[pageNum] or {}
end

function LoginModel:setZoneRoles(zoneId, msg)
	local roles = {}
	for k,v in pairs(msg.users or {}) do
		roles[#roles + 1] = UserBaseInfo.new(v)
	end
	self.rolesDict[zoneId] = roles
    local zoneData = self:getZoneById(zoneId)
    zoneData.roleNum = #roles
end

function LoginModel:getRolesByZoneId(zoneId)
	return self.rolesDict[zoneId]
end

function LoginModel:getRoleCount(zoneId)
	local roles = self:getRolesByZoneId(zoneId)
	return (roles and #roles or 0)
end

function LoginModel:getLastLoginRole(zoneId)
	local roles = self:getRolesByZoneId(zoneId)
	return roles[1]
end

function LoginModel:setSelectZoneListTag(tag)
	self.zoneListDict = {}
	self.zoneCount = -1;
	self._selectZoneListTag = tag
end

function LoginModel:getZoneRange(pageNum)
	local zoneCount = self.zoneCount
	local ibegin = math.max(zoneCount-(pageNum*self.numPerPage)+1,1)
	local iend = zoneCount-(pageNum-1)*self.numPerPage
	--local ibegin = math.max((pageNum-1)*self.numPerPage,0)+1
	--local iend = math.min(pageNum*self.numPerPage,self.zoneCount)
	return ibegin,iend
end

function LoginModel:fetchRange(pageNum,cb)
	-- local ibegin , iend = self:getZoneRange(pageNum)
	local ibegin, iend = 1, 9999
	EM:notify("onFetchRange", {stateIndex = Enums.PwrdTrackEventState.Begin})
	app.channelAPI:fetchServerListByPageNum(function(data, message, zoneCount)
		-- 海外 兼容
		-- if zoneCount ~= nil and self.zoneCount ~= zoneCount then
		-- 	self.zoneCount = zoneCount
		-- 	app:sendMsg("LoginController", "rebuildPageList")
		-- end
		if data then
			self:_parseJsonZoneList(data, pageNum)
			EM:notify("onFetchRange", {stateIndex = Enums.PwrdTrackEventState.Success})
		else
			EM:notify("onFetchRange", {stateIndex = Enums.PwrdTrackEventState.Fail, errorMsg = message})
		end
		if cb then
        	cb(self,message, zoneCount)
    	end
	end, pageNum, ibegin , iend, self._selectZoneListTag)
end

function LoginModel:getPageCount(zoneCount)
	local zoneCount = (zoneCount or self.zoneCount)
	local numPerPage = self.numPerPage
	assert(numPerPage and numPerPage>0)
	local count = zoneCount/numPerPage
	if zoneCount%numPerPage >0 then
		count = count + 1
	end
	return count
end

function LoginModel:clear()
	self.zoneListDict = {}
	self._allZoneServers = {}
end


function LoginModel:_parseJsonZoneList(jsonStr,pageNum)
	self._allZoneServers = {}
	self.recommendZoneList = {}

	local zoneList = {}
	local servers = jsonStr.servers or {}
	local zoneCount = #servers
    for i = 1, zoneCount do
        local zoneJson = servers[i]
        local zoneId = tonumber(zoneJson.id)
        local zoneData = self:JsonToZone(zoneJson)
		self._allZoneServers[zoneData.id] = zoneData
		table.insert(zoneList, zoneData)
		if self:getVisitedZoneById(zoneId) then
			local existedZoneData = self:getVisitedZoneById(zoneId)
			zoneData.roleNum = existedZoneData.roleNum
			zoneData.lastVisitTS = existedZoneData.lastVisitTS
		end

        -- 推荐服
        if zoneData.status == "5" then
        	table.insert(self.recommendZoneList, zoneData)
        end
	end

	-- 更新visitedZoneList数据
	for i,zoneData in pairs(self.visitedZoneList) do
		local newZoneData = self._allZoneServers[zoneData.id]
		if newZoneData then
			zoneData.name = newZoneData.name
			zoneData.addr = newZoneData.addr
			zoneData.status = newZoneData.status
			zoneData.first_opentime = newZoneData.first_opentime
			zoneData.utc = newZoneData.utc
			zoneData.gatehost = newZoneData.gatehost
			zoneData.mergeId = newZoneData.mergeId
		end
	end

	self.zoneCount = zoneCount
	local numPerPage = self.numPerPage or 10
	local pageNum = self:getPageCount()
	local zoneListDict = {}
	for i=1,pageNum do
		local minServer =  math.max(zoneCount-(i*numPerPage)+1,1)
        local maxServer = zoneCount-(i-1)*numPerPage
        zoneListDict[i] = table.sub(zoneList, minServer, maxServer)
	end

	self.zoneListDict = zoneListDict
end

function LoginModel:createRole(info, cb)
	app.session:request("pb_login.C2S_CreateRole", info, function(msg)
            -- print("pb_login.C2S_CreateRole", msg.uid)
            executeFunc(cb, msg)
        end, {block=true})
end

function LoginModel:_deleteRoleSucc(zoneId, uid)
    local zoneData = self:getZoneById(zoneId)
    zoneData.roleNum = zoneData.roleNum - 1

	local roles = self.rolesDict[zoneId]
	for i,role in ipairs(roles) do
		if role.uid == uid then
			display.pushToast(string.format(L("lua_code_text_386"), role.name))
			table.remove(roles, i)
			break
		end
	end
end

function LoginModel:deleteRole(zoneId, uid, cb)
	app.session:request("pb_login.C2S_DeleteRole", {uid=uid}, function(msg)
			if msg.ok then
				self:_deleteRoleSucc(zoneId, uid)
			end
			executeFunc(cb, msg)
		end)
end

-- 获取 同玩好友区服列表
function LoginModel:getMsdkAllFriendZoneList(cb)
	if not UD.msdkData:isFunctionEnable() then
		return {}, true
	end
	
	if self._friendZoneList then
		return self._friendZoneList, true
	end

	local friends = app.channelAPI:queryGameFriendsInfo()
	if not friends then
		return {}, false
	end

	if self._isInFriendZoneList then
		return {}, false
	end

	local platform = app.channelAPI:getWGPlatform()
	local platformName = ""
	if platform == Enums.MSDK_PLATFORM.QQ then
		if app:isAndroid() then
			platformName = "qqand"
		elseif app:isIOS() then
			platformName = "qqios"
		end
	elseif platform == Enums.MSDK_PLATFORM.WX then
		if app:isAndroid() then
			platformName = "wxand"
		elseif app:isIOS() then
			platformName = "wxios"
		end
	else
		platformName = "dev"
	end
	 
	local timestamp = os.time()
	local key = "73736bdb2033e5f88883bb19dc948af1"..timestamp
	local md5Str = cc.Crypto:MD5(key, false)

	local openIds = {}
	local openIdMap = {}
	for k, v in pairs(friends) do
		table.insert(openIds, v.openId)
		openIdMap[v.openId] = v

	end
	if #openIds == 0 then
		self._friendZoneList = {}
		return {}, true
	end


	local openIdStr = table.concat( openIds, "|" )
	local postData = string.format("channel=%s&key=%s&openids=%s&timestamp=%s", platformName, md5Str, openIdStr, timestamp)

	local host = app.channelAPI:getGateHostFromConfig()

	if not host then
		return {}, false
	end
	local  url = host.."getrolesinfo"
	print("===============url====== ", url)
	print("postData  : ", postData)

	self._isInFriendZoneList = true
	app.http.reqJsonData(url,function(response,errorMsg,code)
		self._isInFriendZoneList = false
		 
		if response and response.ret == 0 then
			if response.data then
				local fList = {}
				local t = json.decode(response.data.userdatas)
				if t then
					for k , v in pairs(t) do
						local openId = string.gsub(v.account, "(.-)_(.*)", "%2")
						if openIdMap[openId] then
							v.headUrl = openIdMap[openId].pictureLarge
							v.nickName = openIdMap[openId].nickName
							v.openId = openId
							v.serverInfo = {id = tonumber(v.serverid) or 0, name = v.servername, addr = v.serveraddr, status = v.serverstatus}
							table.insert(fList, v)
						end
							-- v.openId = "F59CCE6DF0017B7FAFA05AC09BE14D35"
							-- v.headUrl = "http://q.qlogo.cn/qqapp/1105873472/F59CCE6DF0017B7FAFA05AC09BE14D35/100"
							-- v.nickname = "测试名字哈哈哈柔柔弱弱若"

							-- v.serverInfo = {id = tonumber(v.serverid) or 0, name = v.servername, addr = v.serveraddr, status = v.serverstatus}
						-- table.insert(fList, v)
					end

					table.sort(fList, function(a, b)
						return a.level < b.level
					end)
					self._friendZoneList = fList
				else
					self._friendZoneList = {}
				end
			else
				self._friendZoneList = {}
			end
		else
			self._friendZoneList = {}
		end

		if cb then
			cb()
		end

	end,"POST",false, postData)
	return {}, false
end


return LoginModel